/*
 * Copyright (c) 2015-2021, www.dibo.ltd (service@dibo.ltd).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * <p>
 * https://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.example.controller;

import com.diboot.core.binding.Binder;
import com.diboot.core.util.D;
import com.diboot.core.util.S;
import com.diboot.core.vo.JsonResult;
import com.diboot.core.vo.Pagination;
import com.example.entity.*;
import com.example.service.*;
import com.example.vo.CitizenDetailVO;
import com.example.vo.DepartmentVO;
import com.example.vo.OldDepartmentVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

/**
* diboot绑定性能对比测试 Controller
* @author MyName
* @version 1.0
* @date 2021-06-25
* Copyright © MyCompany
*/
@RestController
@RequestMapping("/performance")
@Slf4j
public class PerformanceController extends BaseCustomCrudRestController<Citizen> {
    @Autowired
    private DepartmentService departmentService;
    @Autowired
    private OrganizationService organizationService;

    @Autowired
    private CitizenService citizenService;
    @Autowired
    private HouseService houseService;
    @Autowired
    private CitizenHouseService citizenHouseService;

    /**
     * 对比测试部门场景
     * @param pagination
     * @return
     * @throws Exception
     */
    @GetMapping("/compareDept")
    public JsonResult compareDept(Pagination pagination) throws Exception{
        List<Long> xmlTakes = new ArrayList<>();
        List<Long> binderTakes = new ArrayList<>();
        for(int i=0; i<10; i++){
            long startTime = System.currentTimeMillis();
            List<OldDepartmentVO> departmentVOs = departmentService.getDepartmentVOByMybatisXML(600000);
            // 返回结果
            long takes = System.currentTimeMillis() - startTime;
            xmlTakes.add(takes);
            String xmlResult = "mybatis自定义SQL查询，耗时: " + takes + " ms";
            System.out.println(xmlResult);
            System.out.println(departmentVOs.get(0).getOrgName());

            pagination.setPageIndex(30001);
            pagination.setTotalCount(1000000);
            startTime = System.currentTimeMillis();
            // 自动转换为VO并绑定关联对象
            List<DepartmentVO> voList = departmentService.getViewObjectList(null, pagination, DepartmentVO.class);
            takes = System.currentTimeMillis() - startTime;
            binderTakes.add(takes);
            String annoResult = "diboot注解绑定，耗时: " + takes + " ms";
            System.out.println(annoResult);
            System.out.println(voList.get(0).getOrgName());
        }
        long all = 0;
        for(Long take : xmlTakes){
            all += take;
        }
        long avg = all/xmlTakes.size();
        System.out.println("XML自写SQL 平均执行时间: " + avg + " ms");
        all = 0;
        for(Long take : binderTakes){
            all += take;
        }
        avg = all/binderTakes.size();
        System.out.println("diboot绑定 平均执行时间: " + avg + " ms");

        List<String> results = new ArrayList<>(2);
        results.add(S.join(xmlTakes));
        results.add(S.join(binderTakes));
        return JsonResult.OK(results);
    }

    /**
     * 对比测试市民房产场景
     * @param pagination
     * @return
     * @throws Exception
     */
    @GetMapping("/compareCitizen")
    public JsonResult compareCitizen(Pagination pagination) throws Exception{
        List<Long> xmlTakes = new ArrayList<>();
        List<Long> binderTakes = new ArrayList<>();
        for(int i=0; i<10; i++){
            long startTime = System.currentTimeMillis();
            List<CitizenDetailVO> VOs = citizenService.getCitizenVOByMybatisXML(600000);
            // 返回结果
            long takes = System.currentTimeMillis() - startTime;
            xmlTakes.add(takes);
            String xmlResult = "mybatis自定义SQL查询，耗时: " + takes + " ms";
            System.out.println(xmlResult);
            System.out.println(VOs.get(0).getGenderLabel());

            startTime = System.currentTimeMillis();
            pagination.setPageIndex(30001);
            pagination.setTotalCount(1000000);
            // 自动转换为VO并绑定关联对象
            List<CitizenDetailVO> voList = citizenService.getViewObjectList(null, pagination, CitizenDetailVO.class);
            takes = System.currentTimeMillis() - startTime;
            binderTakes.add(takes);
            String annoResult = "diboot注解绑定，耗时: " + takes + " ms";
            System.out.println(annoResult);
            System.out.println(voList.get(0).getGenderLabel());
        }
        long all = 0;
        for(Long take : xmlTakes){
            all += take;
        }
        long avg = all/xmlTakes.size();
        System.out.println("XML自写SQL 平均执行时间: " + avg + " ms");
        all = 0;
        for(Long take : binderTakes){
            all += take;
        }
        avg = all/binderTakes.size();
        System.out.println("diboot绑定 平均执行时间: " + avg + " ms");

        List<String> results = new ArrayList<>(2);
        results.add(S.join(xmlTakes));
        results.add(S.join(binderTakes));
        return JsonResult.OK(results);
    }

    /**
     * 初始化部门场景相关测试数据 - 100W
     * @return
     */
    @GetMapping("/initDeptData")
    public JsonResult initDeptData(){
        List<Organization> organizations = new ArrayList<>();
        List<Department> departments = new ArrayList<>();
        String orgName = "组织X";
        Long[] randomParentIds = new Long[]{10001L, 10002L, 10003L};
        Long startId = 2000000L;
        for(int i=1; i<=10000; i++){
            organizations.clear();
            Organization org = new Organization();
            org.setName(orgName+i);
            org.setParentId(100001L);
            org.setTelphone("0512-283748"+i);
            organizationService.createEntity(org);
            departments.clear();
            for(int j=1; j<=100; j++){
                Department department = new Department();
                department.setOrgId(org.getId());
                department.setParentId(randomParentIds[i%3]);
                department.setName("部门Y"+i);
                department.setId(++startId);
                departments.add(department);
            }
            departmentService.createEntities(departments);
            System.out.println("第"+i+"批数据创建完成！");
        }
        return JsonResult.OK();
    }

    /**
     * 初始化市民场景相关数据 - 100W
     * @return
     */
    @GetMapping("/initCitizenData")
    public JsonResult initCitizenData(){
        List<Citizen> citizens = new ArrayList<>();
        List<House> houses = new ArrayList<>();
        List<CitizenHouse> citizenHouses = new ArrayList<>();
        String[] realnameRandom = {"张", "赵", "孙", "李", "王", "欧阳", "陈", "宋", "徐"};
        String[] realnameRandom2 = {"强", "帅", "武", "斌", "文", "福", "志强", "建国", "立"};
        String[] genderRandom = {"F", "M"};
        for(int i=0; i<10000; i++){
            // 开始一个批次
            citizens.clear();
            houses.clear();
            citizenHouses.clear();
            for(int j=0; j<100; j++){
                Citizen citizen = new Citizen();
                String lastName = realnameRandom[j%9];
                citizen.setRealname(lastName + realnameRandom2[j%9] + j)
                        .setIdCard(S.newRandomNum(18))
                        .setBirthdate(D.convert2Date("1088-08-18"))
                        .setGender("F")
                        .setAddress(genderRandom[j%2])
                        .setMobilephone("13"+S.newRandomNum(9));
                citizens.add(citizen);

                House house = new House().setCity("上海").setArea("浦东新区").setCertNo(S.newRandomNum(20))
                        .setEstateName(lastName+"家花园"+j+"期")
                        .setAddress(lastName+"甲路"+j+"号大街"+j+"号")
                        .setBuildingNo(S.newRandomNum(2)).setDoorNo(S.newRandomNum(4));
                houses.add(house);
            }
            citizenService.createEntities(citizens);
            houseService.createEntities(houses);

            for(Citizen citizen : citizens){
                if(citizen.getId() % 5 == 0){
                    citizenHouses.add(new CitizenHouse().setCitizenId(citizen.getId()).setHouseId(houses.get(0).getId()));
                    citizenHouses.add(new CitizenHouse().setCitizenId(citizen.getId()).setHouseId(houses.get(2).getId()));
                    citizenHouses.add(new CitizenHouse().setCitizenId(citizen.getId()).setHouseId(houses.get(5).getId()));
                    citizenHouses.add(new CitizenHouse().setCitizenId(citizen.getId()).setHouseId(houses.get(7).getId()));
                    citizenHouses.add(new CitizenHouse().setCitizenId(citizen.getId()).setHouseId(houses.get(9).getId()));
                }
            }
            citizenHouseService.createEntities(citizenHouses);
            System.out.println("第"+i+"批数据创建完成！");
        }
        return JsonResult.OK();
    }

} 